package com.zzq.account.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.zzq.account.entities.dto.AccountDTO;
import com.zzq.account.entities.po.converter.AccountConverter;
import com.zzq.account.entities.vo.AccountVO;
import com.zzq.account.service.AccountService;
import com.zzq.common.exception.BusinessException;
import com.zzq.common.result.ResultData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@Slf4j
@RestController
@RequestMapping("/account")
public class AccountController {
    @Autowired
    private AccountService accountService;
    @Autowired
    private AccountConverter accountConverter;

    @PostMapping("/insert")
    public ResultData insert(@RequestBody AccountVO accountVO) throws BusinessException {
        log.info("insert account:{}", accountVO);
        AccountDTO accountDTO = accountConverter.toAccountDTO(accountVO);
        accountService.insertAccount(accountDTO);
        return ResultData.success("insert account succeed");
    }

    @PostMapping("/delete")
    public ResultData delete(@RequestParam String accountCode) {
        log.info("delete account,accountCode is {}", accountCode);
        accountService.deleteAccount(accountCode);
        return ResultData.success("delete account succeed");
    }

    @PostMapping("/update")
    public ResultData update(@RequestBody AccountVO accountVO) {
        log.info("update account:{}", accountVO);
        AccountDTO accountDTO = accountConverter.toAccountDTO(accountVO);
        accountService.updateAccount(accountDTO);
        return ResultData.success("update account succeed");
    }

    @GetMapping("/getByCode/{accountCode}")
    @SentinelResource(value = "getByCode", blockHandler = "handleException", fallback = "fallbackHandler")
    public ResultData getByCode(@PathVariable(value = "accountCode") String accountCode) {
        if ("0".equals(accountCode)) {
            throw new RuntimeException("code:" + accountCode + "无效");
        }
        log.info("get account detail,accountCode is :{}", accountCode);
        AccountDTO accountDTO = accountService.selectByCode(accountCode);
        return ResultData.success(accountDTO);
    }

    /**
     * 自定义异常策略
     * 返回值和参数要跟目标函数一样，参数可以追加BlockException
     */
    public ResultData handleException(@PathVariable("accountCode") String accountCode, BlockException exception) {
        log.info("flow exception{}", exception.getClass().getCanonicalName());
        return ResultData.fail(900, "达到阈值了,不要再访问了!");
    }

    /**
     * 自定义熔断异常
     * 返回值和参数要跟目标函数一样
     */
    public ResultData fallbackHandler(@PathVariable("accountCode") String accountCode) {
        return ResultData.fail(800, "服务被熔断了，不要调用!");
    }
}

